"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 数据库系统
Case Name   : 一主两备，一备进行重建过程中，另一备进行切换，优先保证切换操作
Create At   : 2020/7/6
Owner       : @peilinqian
Description :
    1、备机1进行重建
    2、同时，备机2进行切换
    3、切换完成，重建操作中断(重建操作有概率会成功，需要分情况判断)
    4、再次进行重建
    5、恢复原主备关系
Expect      :
    1、备机1开始进行重建
    2、同时，备机2进行切换成功
    3、切换完成，重建操作中断(重建操作有概率会成功，需要分情况判断)
    4、再次进行重建成功
    5、恢复原主备关系成功
History     :
    modified：2021-4-22 by 5328113;状态结果查询方式变更，修改脚本；
    modified:2021-2-5 by 5328113;增加switchover和build均成功情况判断及状态日志打印
    modified：2021-6-3 by 5328113;适配状态结果查询；
    modified：2022-1-4 by 5321170;build结束后再刷新配置文件
    modified：2022-1-11 by 5321170;优化配置文件刷新
"""

import time
import unittest

from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node


class MyTest(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('----Opengauss_Reliability_Dbsys_Case018.py start----')
        self.pri_root = Node(node='PrimaryRoot')
        self.pri_dbuser = Node(node='PrimaryDbUser')
        self.sta_1_root = Node(node='Standby1Root')
        self.sta_1_dbuser = Node(node='Standby1DbUser')
        self.sta_2_root = Node(node='Standby2Root')
        self.sta_2_dbuser = Node(node='Standby2DbUser')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.sta_1_sh = CommonSH('Standby1DbUser')
        self.sta_2_sh = CommonSH('Standby2DbUser')
        self.com = Common()
        self.constant = Constant()

    def test_main(self):
        self.log.info('----备机1进行重建----')
        build_thread = ComThread(self.sta_1_sh.buildStandby, args=('',))
        build_thread.setDaemon(True)
        build_thread.start()
        time.sleep(4)

        self.log.info('----同时，备机2进行切换----')
        success_msg = self.constant.SWITCH_SUCCESS_MSG
        switch_result = self.sta_2_sh.executeGsctl('switchover',
                                                   success_msg)
        self.assertTrue(switch_result)

        time.sleep(5)
        self.log.info('----查询主备状态----')
        status = self.sta_2_sh.getDbClusterStatus('detail')
        self.log.info(status)
        self.log.info('----查询主机query----')
        self.sta_2_sh.executeGsctl('query', '', get_detail=True)

        build_thread.join(30*60)
        build_result = build_thread.get_result()
        self.log.info(build_result)

        self.log.info('----进行refresh----')
        refresh_msg = self.sta_2_sh.exec_refresh_conf()
        self.log.info(refresh_msg)

        # 验证备机重建失败
        if self.constant.REBUILD_SUCCESS_MSG in build_result:
            if self.constant.SSL_CONNECTION_CLOSED_MSG in build_result:
                if self.constant.CONNECT_SEVER_SUCCESS_MSG in build_result:
                    self.log.info("重连成功，所以重建成功了！符合预期")
                    self.assertTrue(refresh_msg)
            else:
                self.log.info('----没有重连标识log打印，build和switchover均成功----')
                self.log.info('----查询主备状态----')
                status = self.sta_2_sh.getDbClusterStatus('detail')
                self.log.info(status)
                self.log.info('----查询主机query----')
                self.sta_2_sh.executeGsctl('query', '', get_detail=True)
                self.log.info('----备机1再次重建----')
                success_msg = self.constant.BUILD_SUCCESS_MSG
                build_result = self.sta_1_sh.executeGsctl('build',
                                                          success_msg,
                                                          '-b full')
                self.assertTrue(build_result)
                self.assertTrue(refresh_msg)
        else:
            self.log.info("重建失败，符合预期！")

        self.log.info('----验证主备切换后新主备状态标识正确----')
        status = self.sta_2_sh.getDbClusterStatus('detail')
        if status.count('|') > 0:
            list_status_msg = status.splitlines()[-1].strip().split('|')
        else:
            tmp_list = status.split('[  Datanode State   ]')[-1].strip()
            list_status_msg = tmp_list.splitlines()[2::]
        self.log.info(list_status_msg)
        for item_status_msg in list_status_msg:
            if self.sta_2_root.db_host in item_status_msg:
                self.assertIn('Primary Normal', item_status_msg)
            if self.pri_dbuser.db_host in item_status_msg:
                self.assertIn('Standby Normal', item_status_msg)

        self.log.info('----备机1再次重建----')
        result = self.sta_1_sh.build_fail_scp_crtfile()
        self.assertTrue(result)

    def tearDown(self):
        self.log.info('----this is teardown----')
        self.hostmsg = self.pri_dbuser.sh('hostname;').result()
        self.log.info(f'hostname is {self.hostmsg}')
        status = self.pri_sh.check_whether_need_switch(self.hostmsg)
        if status:
            self.pri_sh.executeGsctl('switchover',
                                     self.constant.SWITCHOVER_SUCCESS_MSG)
            self.pri_sh.exec_refresh_conf()
        status = self.pri_sh.check_whether_need_build()
        if status:
            self.sta_1_sh.executeGsctl('build',
                                       self.constant.BUILD_SUCCESS_MSG,
                                       '-b full')
            self.sta_2_sh.executeGsctl('build',
                                       self.constant.BUILD_SUCCESS_MSG,
                                       '-b full')
        self.log.info('----Opengauss_Reliability_Dbsys_Case018执行完成----')
